#include <stdio.h>
#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>

using namespace std;

<<<<<<< HEAD
=======
//int main()
//{
//    int outfd = dup(1);/*备份标准输出的文件描述符*/
//    
//    //我们这一段代码,因为后面把1的文件描述符关闭了
//    //所以讲道理,那么下面的print的函数不会写入文件中
//    //如果把下面的这一句代码屏蔽了,就是上面的那种情况
//    //如果没有屏蔽,那么print函数,会把内容写入文件中
//    //那么具体的原因是什么?
//    
//    //这里是标准输出的缓冲区,在进行缓冲区空间申请设置的时候
//    //设置了行缓冲的标志位,然后在重定向之后,并没有对这个标志位进行重置
//    //所以下面的print里面的'\n'就起到了刷新缓冲区的作用
//    //如果上边没有打印,那么缓冲区一直没有被初始化,直到下边使用的时候
//    //才进行初始化,而这个时候关联的就不是显示器文件了
//    //所以缓冲区没有被设置行缓冲,因此就不会把内容写入文件中
//    printf("%d\n", outfd);
//
//    //  fd = 4
//    int fd = open("./log.txt", O_WRONLY | O_CREAT, 0644);
//
//    dup2(fd, 1);/*将标准输出重定向到fd对应的文件*/
//
//    printf("111111111\n");
//    fprintf(stdout, "222222222\n");
//
//    close(1);
//    return 0;
//}

//从下面的这段代码,可以看出一些端倪
//重定向后,不会重置缓冲的标志
//你第一次使用的是哪个缓冲方式,那么重定向后也是使用的那种缓冲方式
//这里只说明了c语言是这样的

>>>>>>> 6c8f472e6d955de87aafbb713cb19cf25974ebb7
int main()
{
    int outfd = dup(1);/*备份标准输出的文件描述符*/
    
    //我们这一段代码,因为后面把1的文件描述符关闭了
    //所以讲道理,那么下面的print的函数不会写入文件中
    //如果把下面的这一句代码屏蔽了,就是上面的那种情况
    //如果没有屏蔽,那么print函数,会把内容写入文件中
    //那么具体的原因是什么?
    
    //这里是标准输出的缓冲区,在进行缓冲区空间申请设置的时候
    //设置了行缓冲的标志位,然后在重定向之后,并没有对这个标志位进行重置
    //所以下面的print里面的'\n'就起到了刷新缓冲区的作用
    //如果上边没有打印,那么缓冲区一直没有被初始化,直到下边使用的时候
    //才进行初始化,而这个时候关联的就不是显示器文件了
    //所以缓冲区没有被设置行缓冲,因此就不会把内容写入文件中
    printf("%d\n", outfd);

    //  fd = 3
    int fd = open("./log.txt", O_WRONLY | O_CREAT, 0644);
    std::cout << fd << std::endl;

    dup2(fd, 1);/*将标准输出重定向到fd对应的文件*/

    printf("111111111\n");
    fprintf(stdout, "222222222\n");

    close(1);
    return 0;
}

//从下面的这段代码,可以看出一些端倪
//重定向后,不会重置缓冲的标志
//你第一次使用的是哪个缓冲方式,那么重定向后也是使用的那种缓冲方式
//这里只说明了c语言是这样的

//int main()
//{
//    int outfd = dup(1);
//    
//    //printf("outfd: %d\n", outfd);
//
//    int fd = open("./log.txt", O_WRONLY | O_CREAT | O_APPEND, 0664);
//
//    dup2(fd, 1);
//
//    printf("txt\n");
//
//    fflush(stdout);
//
//    dup2(outfd, 1);
//
//    printf("screen\n");
//
//    fd = open("./log.txt", O_WRONLY | O_CREAT | O_APPEND, 0664);
//
//    dup2(fd, 1);
//    printf("test\n");
//
//    dup2(outfd, 1);
//    
//    //fflush(stdout);
//
//    //close(1);
//    close(fd);
//    return 0;
//}

//使用两个printf,一个打印到文件里面,一个打印到屏幕上

//int main()
//{
//    //fileno()用来取得参数stream指定的文件流所使用的文件描述符
//    //返回和stream文件流对应的文件描述符。如果失败，返回-1
//    //dup()系统调用用于生成你传入的文件描述符的一个副本
//    //从未使用的文件描述符当中选取最小的文件描述符作为新的文件描述符
//    //并作为返回值
//    int outfd = dup(1);/*备份标准输出的文件描述符*/
//    
//    //所以这里输出的文件描述符是3
//    printf("outfd: %d\n", outfd);
//
//    //  fd = 4
//    int fd = open("./log.txt", O_WRONLY | O_CREAT | O_APPEND, 0664);
//
//    //dup2将前面的文件描述符内容,复制到后面的文件描述符当中
//    dup2(fd, 1);/*将标准输出重定向到fd对应的文件*/
//
//    printf("txt\n");
//
//    //恢复标准输出
//    dup2(outfd, 1);
//    printf("screen\n");
//
//    close(fd);
//    return 0;
//}

//执行exec系列程序替换的时候,会不会影响我们曾经打开的所有文件?
//是不会的
//只是替换了数据和代码,内核中的相关数据结构,根本不变
//所有关联的文件是不会影响的

//为什么我们打开所有的进程,都会默认打开标准输入,标准输出,标准错误?
//因为父进程如果曾今打开了标准输入,标准输出,标准错误
//子进程会以父进程为模板,构建自己的一份
//其中的内核数据结构也会以模板,来构建一份
//所以子进程和父进程都会打开同一个文件
//而我们在命令行行上运行的程序,它们的父进程都是bash
//bash是默认打开了,标准输出,标准输入,标准错误
//所以子进程会继承

